package com.yinsin.utils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.yinsin.bean.Condition;
import com.yinsin.bean.Condition2;
import com.yinsin.bean.Consumer;

/**
 * 容器类工具类，提供一些常用的方法包括：
 * <ul>
 * <li>List截取，取[x, y]之间的数据</li>
 * <li>将list元素按照chats分隔符分割组合成SQL字符串</li>
 * <li>将list元素按照chats分隔符分割组合成字符串</li>
 * <li>将Array元素按照chats分隔符分割组合成SQL字符串</li>
 * <li>将Array元素按照chats分隔符分割组合成字符串</li>
 * <li>list&lt;对象&gt;去重</li>
 * <li>将List转换为数组</li>
 * <li>将数组转换为List</li>
 * <li>将数组追加到目标List中</li>
 * <li>将数组追加到目标List中，从某个位置插入</li>
 * <li>将List以字符串形式组装</li>
 * <li>将数据追加到目标List中</li>
 * <li>复制List的元素到目标List中</li>
 * <li>合并List的元素到目标List中，合并之后，销毁原List</li>
 * <li>刷新List（去掉为null的数据，List长度会发生变化）</li>
 * <li>刷新Array（去掉为null的数据，Array长度会发生变化）</li>
 * <li>List批量删除元素</li>
 * <li>List获取元素</li>
 * <li>Map元素批量删除</li>
 * <li>Map元素排序并导出到List</li>
 * </ul>
 * 
 * @author Yisin
 * @version 1.13
 * @since jdk1.6
 */
public class CollectionUtils {

	/**
	 * List截取，取[x, y]之间的数据
	 * 
	 * @param list
	 * @param startIndex
	 *            截取的开始位置
	 * @param count
	 *            截取数量
	 * @return 截取后的List
	 */
	public static <T> List<T> pickList(List<T> list, int startIndex, int count) {
		if (count < 0) {
			new IllegalArgumentException("count value is illegality.");
		}
		List<T> newList = new ArrayList<T>();
		if (list != null && count > 0) {
			int k = list.size();
			if (startIndex < 0) {
				startIndex = 0;
			}
			int toIndex = startIndex + count;
			toIndex = toIndex > k ? k : toIndex;
			newList = list.subList(startIndex, toIndex);
		}
		return newList;
	}

	/**
	 * 将list元素按照chats分隔符分割组合成SQL字符串
	 * 
	 * @param list
	 *            List&lt;?&gt;
	 * @return
	 */
	public static String listJoinToSql(List<?> list) {
		String result = "";
		if (list != null) {
			StringBuffer sb = new StringBuffer();
			for (Object obj : list) {
				if (obj instanceof Integer || obj instanceof Double || obj instanceof Float || obj instanceof Short || obj instanceof Long) {
					sb.append(obj).append(",");
				} else {
					sb.append("'").append(obj).append("'").append(",");
				}
			}
			result = sb.toString();
			if (result.length() > 0) {
				result = result.substring(0, result.length() - 1);
			}
		}
		return result;
	}

	/**
	 * 将list元素按照chats分隔符分割组合成SQL字符串
	 * 
	 * @param list
	 * @param chars
	 * @return
	 */
	public static String listJoin(List<?> list, String chars) {
		String result = "";
		if (list != null) {
			StringBuffer sb = new StringBuffer();
			for (Object obj : list) {
				sb.append(CommonUtils.objectToString(obj)).append(chars);
			}
			result = sb.toString();
			if (result.length() > 0) {
				result = result.substring(0, result.length() - chars.length());
			}
		}
		return result;
	}

	/**
	 * 将Array元素按照chats分隔符分割组合成SQL字符串
	 * 
	 * @param array
	 *            Object[]
	 * @return
	 */
	public static String arrayJoinToSql(Object[] array) {
		String result = "";
		if (array != null) {
			StringBuffer sb = new StringBuffer();
			for (Object obj : array) {
				if (obj instanceof Integer || obj instanceof Double || obj instanceof Float || obj instanceof Short || obj instanceof Long) {
					sb.append(obj).append(",");
				} else {
					sb.append("'").append(obj).append("'").append(",");
				}
			}
			result = sb.toString();
			if (result.length() > 0) {
				result = result.substring(0, result.length() - 1);
			}
		}
		return result;
	}

	/**
	 * 将Array元素按照chats分隔符分割组合成字符串
	 * 
	 * @param array
	 *            Object[]
	 * @param chars
	 *            String
	 * @return String
	 */
	public static String arrayJoin(Object[] array, String chars) {
		String result = "";
		if (array != null) {
			StringBuffer sb = new StringBuffer();
			for (Object obj : array) {
				sb.append(CommonUtils.objectToString(obj)).append(chars);
			}
			result = sb.toString();
			if (result.length() > 0) {
				result = result.substring(0, result.length() - chars.length());
			}
		}
		return result;
	}

	/**
	 * list&lt;对象&gt;去重
	 * 
	 * @param list
	 * @return
	 */
	public static List<Serializable> listDelDuplicated(List<Serializable> list) {
		if (list != null) {
			Set<Serializable> ts = new HashSet<Serializable>();
			ts.addAll(list);
			list.clear();
			Iterator<Serializable> ito = ts.iterator();
			while (ito.hasNext()) {
				list.add(ito.next());
			}
		}
		return list;
	}
	
	/**
	 * 将数组转换为List
	 * 
	 * @param array
	 *            Object[]
	 * @return list
	 */
	public static <T> List<T> arrayToList(T[] array) {
		if (array == null) {
			throw new NullPointerException("array is nullable.");
		}
		return arrayAppendToList(new ArrayList<T>(), array);
	}

	/**
	 * 将数组转换为List
	 * 
	 * @param array
	 *            String[]
	 * @return list
	 */
	public static List<String> arrayToList(String[] array) {
		if (array == null) {
			throw new NullPointerException("array is nullable.");
		}
		return arrayAppendToList(new ArrayList<String>(), array);
	}

	/**
	 * 将数组转换为List
	 * 
	 * @param array
	 *            int[]
	 * @return list
	 */
	public static List<? extends Integer> arrayToList(int[] array) {
		if (array == null) {
			throw new NullPointerException("array is nullable.");
		}
		return arrayAppendToList(new ArrayList<Integer>(), array);
	}

	/**
	 * 将数组转换为List
	 * 
	 * @param array
	 *            double[]
	 * @return list
	 */
	public static List<? extends Double> arrayToList(double[] array) {
		if (array == null) {
			throw new NullPointerException("array is nullable.");
		}
		return arrayAppendToList(new ArrayList<Double>(), array);
	}

	/**
	 * 将数组追加到目标List中
	 * 
	 * @param desList
	 *            目标List
	 * @param array
	 *            数组
	 * @return desList
	 */
	public static <T> List<T> arrayAppendToList(List<T> desList, T[] array) {
		if (desList == null) {
			throw new NullPointerException("target list is nullable.");
		}
		if (array != null) {
			for (T obj : array) {
				desList.add(obj);
			}
		}
		return desList;
	}

	/**
	 * 将数组追加到目标List中
	 * 
	 * @param desList
	 *            目标List
	 * @param array
	 *            数组
	 * @return desList
	 */
	public static List<Float> arrayAppendToList(List<Float> desList, float[] array) {
		if (desList == null) {
			throw new NullPointerException("target list is nullable.");
		}
		if (array != null) {
			for (Float obj : array) {
				desList.add(obj);
			}
		}
		return desList;
	}

	/**
	 * 将数组追加到目标List中
	 * 
	 * @param desList
	 *            目标List
	 * @param array
	 *            数组
	 * @return desList
	 */
	public static List<Integer> arrayAppendToList(List<Integer> desList, int[] array) {
		if (desList == null) {
			throw new NullPointerException("target list is nullable.");
		}
		if (array != null) {
			for (Integer obj : array) {
				desList.add(obj);
			}
		}
		return desList;
	}

	/**
	 * 将数组追加到目标List中
	 * 
	 * @param desList
	 *            目标List
	 * @param array
	 *            数组
	 * @return desList
	 */
	public static List<Double> arrayAppendToList(List<Double> desList, double[] array) {
		if (desList == null) {
			throw new NullPointerException("target list is nullable.");
		}
		if (array != null) {
			for (Double obj : array) {
				desList.add(obj);
			}
		}
		return desList;
	}

	/**
	 * 将数组追加到目标List中，从某个位置插入
	 * 
	 * @param desList
	 *            目标List
	 * @param array
	 *            数组
	 * @param startIndex
	 *            开始索引位置(从0开始)，若 &lt; 0 则默认为0，若大于目标List的长度，则中间以null填充
	 * @return desList 目标List
	 */
	public static <T> List<T> arrayAppendToList(List<T> desList, T[] array, int startIndex) {
		if (desList == null) {
			throw new NullPointerException("target list is nullable.");
		}
		if (startIndex < 0) {
			startIndex = 0;
		}
		// 开始处理
		if (startIndex >= desList.size()) {
			CollectionUtils.arrayAppendToList(desList, array);
		} else if (startIndex == 0) {
			List<T> newList = arrayToList(array);
			desList = CollectionUtils.copyListTo(desList, newList);
		} else {
			List<T> list = pickList(desList, 0, startIndex);
			CollectionUtils.arrayAppendToList(list, array);
		}
		return desList;
	}
	
	/**
     * 将List转换为数组
     * 
     * @param list
     * @return
     */
    public static Object[] listToArray(List<?> list) {
        Object[] objArr = null;
        if (list != null) {
            objArr = list.toArray();
        }
        return objArr;
    }

	/**
	 * 将List以字符串形式组装
	 * 
	 * @param list
	 * @return
	 */
	public static String listToString(List<?> list) {
		String result = "[";
		if (list != null && list.size() > 0) {
			StringBuffer sb = new StringBuffer();
			for (Object obj : list) {
				if (obj != null) {
					sb.append(String.valueOf(obj));
				} else {
					sb.append("null");
				}
				sb.append(", ");
			}
			result += sb.toString();
			result = result.substring(0, result.length() - 2);
		}
		return result + "]";
	}

	/**
	 * 将数组以字符串形式组装
	 * 
	 * @param array
	 *            Object[]
	 * @return
	 */
	public static String arrayToString(Object[] array) {
		return CollectionUtils.listToString(CollectionUtils.arrayToList(array));
	}

	/**
	 * 将数组以字符串形式组装
	 * 
	 * @param array
	 *            String[]
	 * @return
	 */
	public static String arrayToString(String[] array) {
		return CollectionUtils.listToString(CollectionUtils.arrayToList(array));
	}

	/**
	 * 将数组以字符串形式组装
	 * 
	 * @param array
	 *            int[]
	 * @return
	 */
	public static String arrayToString(int[] array) {
		return CollectionUtils.listToString(CollectionUtils.arrayToList(array));
	}

	/**
	 * 将数组以字符串形式组装
	 * 
	 * @param array
	 *            double[]
	 * @return
	 */
	public static String arrayToString(double[] array) {
		return CollectionUtils.listToString(CollectionUtils.arrayToList(array));
	}

	/**
	 * 将数据追加到目标List中
	 * 
	 * @param list
	 *            目标List
	 * @param value
	 *            数据项（多项）
	 * @return List
	 */
	public static <T> List<T> appendToList(List<T> list, T... value) {
		if (list == null) {
			throw new NullPointerException("target list is nullable.");
		}
		if (value != null) {
			for (int i = 0; i < value.length; i++) {
				list.add(value[i]);
			}
		}
		return list;
	}

	/**
	 * 复制List的元素到目标List中
	 * 
	 * @param resList
	 *            要被复制的List
	 * @param destList
	 *            目标List
	 * @return 合并后的目标List
	 */
	public static <T> List<T> copyList(List<T> resList) {
		List<T> destList = null;
		if (resList != null) {
			destList = new ArrayList<T>();
			for (T object : resList) {
				destList.add(object);
			}
		}
		return destList;
	}
	
	/**
	 * 复制List的元素到目标List中
	 * 
	 * @param resList
	 *            要被复制的List
	 * @param destList
	 *            目标List
	 * @return 合并后的目标List
	 */
	public static <T> List<T> copyListTo(List<T> resList, List<T> destList) {
		if (destList == null) {
			throw new NullPointerException("target list is nullable.");
		}
		if (resList != null) {
			for (T object : resList) {
				destList.add(object);
			}
		}
		return destList;
	}

	/**
	 * 合并List的元素到目标List中，合并之后，销毁原List
	 * 
	 * @param resList
	 * @param destList
	 * @return
	 */
	public static <T> List<T> megreListTo(List<T> resList, List<T> destList) {
		CollectionUtils.copyListTo(resList, destList);
		resList.clear();
		resList = null;
		return destList;
	}

	/**
	 * 刷新List（去掉为null的数据，List长度会发生变化）
	 * @new clearNull
	 * @param list
	 * @return list
	 */
	@Deprecated
	public static <T> List<T> flushList(List<T> list) {
		if (list != null) {
			Iterator<T> iter = list.iterator();
			T t = null;
			while(iter.hasNext()){
				t = iter.next();
				if(null == t){
					iter.remove();
				}
			}
		}
		return list;
	}
	
	/**
	 * 清除List为null的项（去掉为null的数据，List长度会发生变化）
	 * 
	 * @param list
	 * @return list
	 */
	public static <T> List<T> clearNull(List<T> list) {
		if (list != null) {
			Iterator<T> iter = list.iterator();
			T t = null;
			while(iter.hasNext()){
				t = iter.next();
				if(null == t){
					iter.remove();
				}
			}
		}
		return list;
	}

	/**
	 * 刷新Array（去掉为null的数据，Array长度会发生变化）
	 * 
	 * @new clearNull
	 * @param array
	 * @return array
	 */
	@Deprecated
	public static <T> T[] flushArray(T[] array) {
		if (array != null) {
			List<T> list = arrayToList(array);
			array = flushList(list).toArray(array);
			array = Arrays.copyOf(array, list.size());
		}
		return array;
	}
	
	/**
	 * 刷新Array（去掉为null的数据，Array长度会发生变化）
	 * 
	 * @param array
	 * @return array
	 */
	public static <T> T[] clearNull(T[] array) {
		if (array != null) {
			List<T> list = arrayToList(array);
			array = clearNull(list).toArray(array);
			array = Arrays.copyOf(array, list.size());
		}
		return array;
	}

	/**
	 * 获取数组中最大数值的索引（只拿第1个）
	 * 
	 * @param array
	 * @return
	 */
	public static int getMaxIndex(int[] array) {
		int result = -1;
		int[] res = array.clone();
		Arrays.sort(res);
		int max = res[res.length - 1];
		for (int i = 0; i < array.length; i++) {
			if (array[i] == max) {
				result = i;
				break;
			}
		}
		return result;
	}

	/**
	 * 获取数组中最大数值的索引(多个)
	 * 
	 * @param array
	 * @return
	 */
	public static int[] getMaxsIndex(int[] array) {
		int[] res = array.clone();
		Arrays.sort(res);
		int max = res[res.length - 1];
		List<Integer> list = new ArrayList<Integer>();
		for (int i = 0; i < array.length; i++) {
			if (array[i] == max) {
				list.add(i);
			}
		}
		int[] result = new int[list.size()];
		for (int i = 0, k = list.size(); i < k; i++) {
			result[i] = list.get(i);
		}
		return result;
	}

	/**
	 * List批量删除元素
	 * @param resList
	 * @param start
	 * @param end
	 * @return
	 */
	public static <T> List<T> listRemove(List<T> resList, int start, int end) {
		if (end < start || start >= resList.size()) {
			throw new ArrayIndexOutOfBoundsException();
		}
		List<T> delList = new ArrayList<T>();
		for (int i = start; i <= end; i++) {
			delList.add(resList.get(i));
		}
		return listRemove(resList, delList);
	}

	/**
	 * List批量删除元素
	 * @param resList
	 * @param removeList
	 * @return
	 */
	public static <T> List<T> listRemove(List<T> resList, List<T> removeList) {
		Iterator<T> tIter = resList.iterator();
		T t = null;
		int count = removeList.size();
		int num = 0;
		while (tIter.hasNext() && num < count) {
			t = tIter.next();
			for (T obj : removeList) {
				if (t == obj || (null != obj && obj.equals(t))) {
					tIter.remove();
					num++;
					break;
				}
			}
		}
		return resList;
	}
	
	/**
	 * List批量删除元素
	 * @param resList
	 * @param removeIndexs
	 * @return
	 */
	public static <T> List<T> listRemove(List<T> resList, T... items) {
		List<T> delList = new ArrayList<T>();
		for (T t : items) {
			delList.add(t);
		}
		return listRemove(resList, delList);
	}

	/**
	 * List批量删除元素
	 * @param resList
	 * @param removeIndexs
	 * @return
	 */
	public static <T> List<T> listRemove(List<T> resList, int... removeIndexs) {
		List<T> delList = new ArrayList<T>();
		for (int i : removeIndexs) {
			delList.add(resList.get(i));
		}
		return listRemove(resList, delList);
	}

	/**
	 * List批量删除元素
	 * @param resList
	 * @param condition
	 * @return
	 */
	public static <T> List<T> listRemove(List<T> resList, Condition<T> condition) {
		Iterator<T> tIter = resList.iterator();
		T t = null;
		while (tIter.hasNext()) {
			t = tIter.next();
			if (condition.is(t)) {
				tIter.remove();
			}
		}
		return resList;
	}
	
	/**
	 * List获取元素
	 * @param resList
	 * @param condition
	 * @return
	 */
	public static <T> T listGet(List<T> resList, Condition<T> condition) {
		Iterator<T> tIter = resList.iterator();
		T t = null;
		while (tIter.hasNext()) {
			t = tIter.next();
			if (condition.is(t)) {
				return t;
			}
		}
		return null;
	}
	
	/**
	 * List获取元素
	 * @param resList
	 * @param condition
	 * @return
	 */
	public static <T> List<T> listGets(List<T> resList, Condition<T> condition) {
		List<T> tlist = new ArrayList<T>();
		Iterator<T> tIter = resList.iterator();
		T t = null;
		while (tIter.hasNext()) {
			t = tIter.next();
			if (condition.is(t)) {
				tlist.add(t);
			}
		}
		return tlist;
	}
	
	/**
	 * Map元素批量删除
	 * @param resMap
	 * @param removeMap
	 * @return
	 */
	public static <T, V> Map<T, V> mapRemove(Map<T, V> resMap, Map<T, V> removeMap){
		Iterator<Map.Entry<T, V>> it = resMap.entrySet().iterator();
		Map.Entry<T, V> entry = null;
		while(it.hasNext()){
			entry = it.next();
			if(null != entry){
				if(removeMap.containsKey(entry.getKey()) && removeMap.get(entry.getKey()) == entry.getValue()){
					it.remove();
				}
			}
		}
		return resMap;
	}
	
	/**
	 * Map元素批量删除
	 * @param resMap
	 * @param removeList
	 * @return
	 */
	public static <T, V> Map<T, V> mapRemove(Map<T, V> resMap, List<V> removeList){
		Iterator<Map.Entry<T, V>> it = resMap.entrySet().iterator();
		Map.Entry<T, V> entry = null;
		int max = removeList.size();
		int count = 0;
		while(it.hasNext() && count < max){
			entry = it.next();
			if(null != entry){
				for(V v : removeList){
					if(v == entry.getValue() || (null != v && v.equals(entry.getValue()))){
						it.remove();
						count++;
						break;
					}
				}
			}
		}
		return resMap;
	}
	
	/**
	 * Map元素批量删除
	 * @param resMap
	 * @param items
	 * @return
	 */
	public static <T, V> Map<T, V> mapRemove(Map<T, V> resMap, V... items){
		Iterator<Map.Entry<T, V>> it = resMap.entrySet().iterator();
		Map.Entry<T, V> entry = null;
		int max = items.length;
		int count = 0;
		while(it.hasNext() && count < max){
			entry = it.next();
			if(null != entry){
				for(V v : items){
					if(v == entry.getValue() || (null != v && v.equals(entry.getValue()))){
						it.remove();
						count++;
						break;
					}
				}
			}
		}
		return resMap;
	}
	
	/**
	 * Map元素批量删除
	 * @param resMap
	 * @param items
	 * @return
	 */
	public static <T, V> Map<T, V> mapRemove(Map<T, V> resMap, Condition2<T, V> condition){
		Iterator<Map.Entry<T, V>> it = resMap.entrySet().iterator();
		Map.Entry<T, V> entry = null;
		while(it.hasNext()){
			entry = it.next();
			if(null != entry){
				if(condition.is(entry.getKey(), entry.getValue())){
					it.remove();
				}
			}
		}
		return resMap;
	}
	
	/**
	 * Map元素批量删除
	 * @param resMap
	 * @param removeList
	 * @return
	 */
	public static <T, V> Map<T, V> mapRemoveByKeys(Map<T, V> resMap, List<T> removeList){
		Iterator<Map.Entry<T, V>> it = resMap.entrySet().iterator();
		Map.Entry<T, V> entry = null;
		int max = removeList.size();
		int count = 0;
		while(it.hasNext() && count < max){
			entry = it.next();
			if(null != entry){
				for(T t : removeList){
					if(t == entry.getKey() || (null != t && t.equals(entry.getKey()))){
						it.remove();
						count++;
						break;
					}
				}
			}
		}
		return resMap;
	}
	
	/**
	 * Map元素批量删除
	 * @param resMap
	 * @param items
	 * @return
	 */
	public static <T, V> Map<T, V> mapRemoveByKeys(Map<T, V> resMap, T... items){
		Iterator<Map.Entry<T, V>> it = resMap.entrySet().iterator();
		Map.Entry<T, V> entry = null;
		int max = items.length;
		int count = 0;
		while(it.hasNext() && count < max){
			entry = it.next();
			if(null != entry){
				for(T t : items){
					if(t == entry.getKey() || t.equals(entry.getKey())){
						it.remove();
						count++;
						break;
					}
				}
			}
		}
		return resMap;
	}

	/**
	 * Map元素排序并导出到List
	 * @param resMap
	 * @param c
	 * @return
	 */
	public static <T, V> List<V> mapSortToList(Map<T, V> resMap, Comparator<? super V> c){
		List<V> desList = new ArrayList<V>();
		for(Map.Entry<T, V> entry : resMap.entrySet()){  
			desList.add(entry.getValue());
		}
		desList.sort(c);
		return desList;
	}
	
	/**
	 * Map元素将key排序并导出到List
	 * @param resMap
	 * @param c
	 * @return
	 */
	public static <T, V> List<T> mapSortKeyToList(Map<T, V> resMap, Comparator<? super T> c){
		List<T> desList = new ArrayList<T>();
		for(Map.Entry<T, V> entry : resMap.entrySet()){  
			desList.add(entry.getKey());
		}
		desList.sort(c);
		return desList;
	}
	
	/**
	 * 集合遍历
	 * @param coll
	 * @param c
	 * @return
	 */
	public static <T> void listFor(Collection<T> coll, Consumer<? super T> c){
		Iterator<T> tIter = coll.iterator();
		T t = null;
		while (tIter.hasNext()) {
			t = tIter.next();
			c.accept(t);
			if(c.jumpout()){
				return;
			}
		}
	}
	
}
